package cn.yangliu.jpa.tools;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import cn.yangliu.jpa.enums.DbTypeEnum;
import cn.yangliu.jpa.enums.LinkTypeEnum;
import lombok.SneakyThrows;

/**
 * @author 杨柳
 * @date 2019-06-15
 */
public class JpaUtils {

    public static final String WHERE = " where ";

    public static DbTypeEnum defaultDbType = DbTypeEnum.MYSQL;

    public static final ThreadLocal<DbTypeEnum> THREAD_LOCAL = new ThreadLocal<>();


    /**
     * 获取查询对象的所有属性 获取父类属性是为了保证继承
     *
     * @param object 查询条件封装 或者class对象
     * @return 属性集合
     */
    public static List<Field> getDeclaredFields(Object object) {
        Class<?> clazz;
        if (object instanceof Class) {
            clazz = (Class) object;
        } else {
            clazz = object.getClass();
        }

        List<Field> fieldList = new ArrayList<>();
        while (!clazz.equals(Object.class)) {
            Field[] fields = clazz.getDeclaredFields();
            if (fields.length > 0) {
                fieldList.addAll(Arrays.asList(fields));
            }
            clazz = clazz.getSuperclass();
        }
        return fieldList;
    }

    public static String linkType(LinkTypeEnum linkType, boolean whereFlag) {
        if (!whereFlag) {
            return "";
        }
        return " " + linkType.name() + " ";
    }


    /**
     * 获取属性值
     *
     * @param queryPojo 查询对象
     * @param field     属性
     * @return 值
     */
    @SneakyThrows
    public static Object getFieldValue(Object queryPojo, Field field) {
        boolean accessible = field.isAccessible();
        if (!accessible) {
            field.setAccessible(true);
        }
        Object value = field.get(queryPojo);

        if (!accessible) {
            field.setAccessible(false);
        }
        return value;
    }

    /**
     * 驼峰转下划线
     *
     * @param para 源字符串
     * @return 带下划线的字符串
     */
    public static String humpToUnderline(String para) {
        StringBuilder sb = new StringBuilder(para);
        //定位
        int temp = 0;
        if (!para.contains("_")) {
            for (int i = 0; i < para.length(); i++) {
                if (Character.isUpperCase(para.charAt(i))) {
                    sb.insert(i + temp, "_");
                    temp += 1;
                }
            }
        }
        return sb.toString().toUpperCase();
    }

    @SneakyThrows
    public static void setFieldValue(Object object, Field field, Object value) {
        boolean accessible = field.isAccessible();
        if (!accessible) {
            field.setAccessible(true);
        }
        field.set(object, value);

        if (!accessible) {
            field.setAccessible(false);
        }
    }


    public static void buildArrayParams(StringBuilder sb, Object value) {
        sb.append(" (");
        if (value.getClass().isArray()) {
            Object[] array = (Object[]) value;
            for (int i = 0; i < array.length; i++) {
                if (array[i] instanceof String) {
                    sb.append("'").append(array[i].toString()).append("'");
                    if (i + 1 != array.length) {
                        sb.append(",");
                    }
                }
                if (array[i] instanceof Number) {
                    sb.append(array[i]);
                    if (i + 1 != array.length) {
                        sb.append(",");
                    }
                }

            }
        }
        if (value instanceof Collection) {
            Collection collection = (Collection) value;
            int index = 0;
            for (Object o : collection) {
                if (o instanceof String) {
                    sb.append("'").append(o.toString()).append("'");
                    if ((index + 1) != collection.size()) {
                        sb.append(",");
                    }
                }
                if (o instanceof Number) {
                    sb.append(o);
                    if ((index + 1) != collection.size()) {
                        sb.append(",");
                    }
                }
                index++;
            }
        }
        sb.append(" ) ");
    }

    public static boolean isNotEmptyArray(Object value) {
        if (Objects.isNull(value)) {
            return false;
        }
        return (value.getClass().isArray() && ((Object[]) value).length > 0) || ((value instanceof Collection) && ((Collection) value).size() > 0);
    }
}